home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks96 / FlyPaper.sit / Fly Paper / FlyPaper Source / App Sources / FlyPaperApp.cpp < prev    next >
C/C++ Source or Header  |  1996-06-22  |  9KB  |  393 lines

  1. #include <new.h>
  2.  
  3. #ifndef FLYPAPERAPP_H
  4. #include "FlyPaperApp.h"
  5. #endif
  6.  
  7. #ifndef FLYPAPERINIT_H
  8. #include "FlyPaperINIT.h"
  9. #endif
  10.  
  11. #ifndef MAGICWINDOW_H
  12. #include "MagicWindow.h"
  13. #endif
  14.  
  15. #ifndef FLYPAPERUTILS_H
  16. #include "FlyPaperUtils.h"
  17. #endif
  18.  
  19. #ifndef CLIPPINGFILE_H
  20. #include "ClippingFile.h"
  21. #endif
  22.  
  23. #ifndef CLIPPINGWINDOW_H
  24. #include "ClippingWindow.h"
  25. #endif
  26.  
  27. #ifndef FLYPAPERERRORS_H
  28. #include "FlyPaperErrors.h"
  29. #endif
  30.  
  31. #include <Fonts.h>
  32. #include <Resources.h>
  33. #include <ToolUtils.h>
  34. #include <Windows.h>
  35. #include <Gestalt.h>
  36. #include <TextServices.h>
  37. #include <drag.h>
  38. #include "Patches.h"
  39. #include "Filter.h"
  40. #include "Floaters.h"
  41.  
  42. Boolean                    gHasColorQD;
  43. Boolean                    gRunning = true;
  44. Ptr                        gFilterProc = nil;
  45. FlyPaperGestaltPtr        gFlyPaperINITData = nil;
  46. GlobalsRec                glob;
  47. short                    gResFile = -1;
  48. Str255                    gClippingsFolderName;
  49. FSSpec**                gPendingFiles = nil;
  50. short                    gNumPendingFiles = 0;
  51. ProcessSerialNumber        gMyPSN;
  52.  
  53. void            CheckGestalts (void);
  54. pascal OSErr    UniversalAEHandler (AppleEvent* theEvent, AppleEvent* theReply, long refCon);
  55. void            Initialize (void);
  56. void            EventLoop ();
  57. void            CheckForNewClippings ();
  58. void            LoadClippings ();
  59.  
  60. FlyPaperGestaltPtr GetINITData ()
  61. {
  62.     if (gFlyPaperINITData == NULL) {
  63.         Gestalt (kSignature, (long*) &gFlyPaperINITData);
  64.     }
  65.     return gFlyPaperINITData;
  66. }
  67.  
  68. void    CheckGestalts (void)
  69. {
  70.     long        gestaltResponse;
  71.     OSErr        error;
  72.     
  73.     error = Gestalt (gestaltQuickdrawFeatures, &gestaltResponse);
  74.     if (error)
  75.         throw error;
  76.     
  77.     gHasColorQD = gestaltResponse & (1 << gestaltHasColor);
  78.     error = Gestalt (gestaltDragMgrAttr, &gestaltResponse);
  79.     if (error)
  80.         throw kNoDragManagerErr;
  81. }
  82.  
  83. pascal
  84. OSErr UniversalAEHandler (AppleEvent* theEvent, AppleEvent* theReply, long refCon)
  85. {
  86.     if (refCon == kAEQuitApplication)
  87.         gRunning = false;
  88.     return noErr;
  89. }
  90.  
  91. static
  92. void NewHandler ()
  93. {
  94.     DebugStr ("\p ### New failed");
  95.     throw (OSErr) memFullErr;
  96. }
  97.  
  98. void    Initialize (void)
  99. {
  100. #if BGONLY
  101.     SetApplLimit (GetApplLimit() - 16384);    // give us a 16K stack instead of 8K
  102. #endif
  103.  
  104.     MaxApplZone ();
  105.     InitGraf (&qd.thePort);
  106.     // Background-only apps are not supposed to do this, but it is necessary in order for
  107.     // FindServiceWindow to work correctly.  ••• I am not 100% sure of the consequences!
  108.     
  109.     InitFonts ();
  110.     InitMenus ();
  111.     TEInit ();        // TextBox requires this.
  112.     
  113. #if !BGONLY
  114.     
  115.     InitFonts ();
  116.     InitWindows ();
  117.     InitMenus ();
  118.     TEInit ();
  119.     InitDialogs (NULL);
  120.     
  121. #endif
  122.  
  123.     // remember our PSN for later
  124.     ProcessInfoRec            pInfo;
  125.     ProcessSerialNumber        psn = { 0, kCurrentProcess };
  126.     
  127.     pInfo.processInfoLength = sizeof (pInfo);
  128.     pInfo.processName = nil;
  129.     pInfo.processAppSpec = nil;
  130.  
  131.     OSErr            error = GetProcessInformation (&psn, &pInfo);
  132.     if (error)
  133.         throw error;
  134.     
  135.     gMyPSN = pInfo.processNumber;
  136.  
  137.     gPendingFiles = (FSSpec**) TempNewHandle (0, &error);
  138.     
  139.     if (error)
  140.         throw error;
  141.  
  142.     // Remember our app's res file
  143.     gResFile = CurResFile ();
  144.  
  145.     GetIndString (gClippingsFolderName, kMiscStrs, kClippingsFolderStr);
  146.     if (gClippingsFolderName [0] == '\0')
  147.         throw resNotFound;
  148.         
  149.     // Install our AppleEvent handlers
  150.     AEEventHandlerUPP        proc = NewAEEventHandlerProc (UniversalAEHandler);
  151.     if (!proc)
  152.         throw memFullErr;
  153.     
  154.     error = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, proc, kAEOpenApplication, false);
  155.     if (error)
  156.         throw error;
  157.     error = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, proc, kAEOpenDocuments, false);
  158.     if (error)
  159.         throw error;
  160.     error = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, proc, kAEPrintDocuments, false);
  161.     if (error)
  162.         throw error;
  163.     error = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, proc, kAEQuitApplication, false);
  164.     if (error)
  165.         throw error;
  166.  
  167.     GetCurrentProcess (&glob.myPSN);
  168.  
  169.     // Install our patches (local to this process, of course)
  170.     if (gHasColorQD)
  171.         PatchNewWindow ();
  172.     
  173.     PatchExitToShell ();
  174.  
  175.     // Install the GNEFilter
  176.     gFilterProc = InstallEventFilter ((FilterHelperUPP) EventFilterHelper, (Ptr) GetCurrentA5 ());
  177.     if (!gFilterProc)
  178.         throw memFullErr;
  179. }
  180.  
  181. void Finalize (void)
  182. {
  183.     // do any panic cleanup
  184.     static Boolean        beenHereDoneThat = false;
  185.  
  186.     try {
  187.         if (!beenHereDoneThat) {        // prevent potential recursion
  188.             beenHereDoneThat = true;
  189.             CloseRemainingFloaters();
  190.             if (gFilterProc) {
  191.                 ReleaseEventFilter(gFilterProc);
  192.                 gFilterProc = false;
  193.             }
  194.             if (gPendingFiles) {
  195.                 gNumPendingFiles = 0;
  196.                 DisposeHandle ((Handle) gPendingFiles);
  197.                 gPendingFiles = nil;
  198.             }
  199.         }
  200.     } catch (...) {
  201.     }
  202. }
  203.  
  204. void EventLoop ()
  205. {
  206.     Boolean floaterEvent;
  207.     
  208.     // If there are no internal events pending, then we call WNE() with a
  209.     //   moderate delay. Otherwise, we want to make a fast response to any 
  210.     //   floater events, so we make sure the event filter will wake us up quickly.
  211.     if (! glob.forwardedEvents.qHead) 
  212.         WaitNextEvent(everyEvent, &glob.theEvent, 60 * 5, 0);
  213.     
  214.     // If nothing to do, then check our private event queue to see if any
  215.     //   clicks or keydowns are pending for our floater windows.
  216.     floaterEvent = (glob.theEvent.what != nullEvent) ? false : 
  217.             GetFloaterEvent(&glob.theEvent);
  218.     
  219.     // Check the states of our floaters, then generate and handle any 
  220.     //   pending Update Events for floaters because the Event Mgr will
  221.     //   not generate them for us.
  222.     ShowHideFloater(0);
  223.     UpdateFloater(0);
  224.  
  225.     switch (glob.theEvent.what) {
  226.     
  227.         case nullEvent : break;
  228.         case mouseDown :
  229.             short            thePart;
  230.             Rect            bounds;
  231.             WindowPtr        whichWin, frontWin;
  232.                         
  233.             if (floaterEvent) {
  234.                 thePart = FindServiceWindow (glob.theEvent.where, &whichWin);
  235.                 if (GetFrontServiceWindow (&frontWin))
  236.                     frontWin = nil;
  237.             } else {
  238.                 thePart = FindWindow (glob.theEvent.where, &whichWin);
  239.                 frontWin = FrontWindow();
  240.             }
  241.  
  242.             glob.theEvent.message = thePart;
  243.                 
  244.             switch(thePart) {
  245.                 case inMenuBar : break;
  246.                 case inSysWindow : SystemClick(&glob.theEvent, whichWin); break;
  247.                     
  248.                 case inGoAway :
  249.                     if (TrackGoAway (whichWin, glob.theEvent.where))
  250.                         DisposeFloater (whichWin);
  251.                     break;
  252.                     
  253.                 case inDrag:
  254.                 case inGrow :
  255.                 case inZoomIn :
  256.                 case inZoomOut :
  257.                     if (whichWin != frontWin) {
  258.                         SelectWindow (whichWin);
  259.                         UpdateFloater (whichWin);
  260.                     }
  261.                     
  262.                     bounds = (**GetGrayRgn()).rgnBBox;
  263.                     DragWindow (whichWin, glob.theEvent.where, &bounds);
  264.                     UpdateFloater (whichWin);
  265.                     break;
  266.                     
  267.                 case inContent :
  268.                     if (whichWin != frontWin) {
  269.                         SelectWindow (whichWin);
  270.                         UpdateFloater (whichWin);
  271.                     }
  272.                     
  273.                     EventDispatchFloaters (&glob.theEvent, whichWin);
  274.                     break;
  275.             }
  276.             break;
  277.  
  278.         case keyDown :
  279.         case autoKey :
  280.             gRunning = false;
  281.             break;
  282.                 
  283.         case updateEvt:
  284.             if (GetOneFloater ((WindowPtr) glob.theEvent.message, false))
  285.                 EventDispatchFloaters (&glob.theEvent, (WindowPtr) glob.theEvent.message);
  286.             break;
  287.         case activateEvt:
  288.             break;
  289.         case kHighLevelEvent:
  290.             OSErr            error = AEProcessAppleEvent(&glob.theEvent);
  291.             if (error)
  292.                 throw error;
  293.             break;
  294.         }
  295.  
  296.     try {
  297.         ProcessPendingFiles ();
  298.     } catch (...) {
  299.     }
  300. }
  301.  
  302. void LoadClippings ()
  303. {    
  304.     CInfoPBRec                pb;
  305.     FSSpec                    spec;
  306.     long                    dirID;
  307.         
  308.     OSErr                    error = FlyPaperFindFolder (kOnSystemDisk, kClippingsFolder, true,
  309.                                 &pb.hFileInfo.ioVRefNum, &dirID);
  310.     if (error)
  311.         throw error;
  312.     
  313.     pb.hFileInfo.ioNamePtr = spec.name;
  314.     spec.name [0] = 0;
  315.     spec.parID = dirID;
  316.     spec.vRefNum = pb.hFileInfo.ioVRefNum;
  317.     
  318.     for (pb.hFileInfo.ioFDirIndex = 1; ; ++pb.hFileInfo.ioFDirIndex) {
  319.         
  320.         pb.hFileInfo.ioDirID = dirID;
  321.         if (PBGetCatInfoSync (&pb))
  322.             break;
  323.         
  324.         if (pb.hFileInfo.ioFlFndrInfo.fdType != kMyClippingType)
  325.             continue;
  326.     
  327.         CClippingFile*            file = new CClippingFile (spec);
  328.         try {
  329.             CClippingWindow*        window = new CClippingWindow (file);
  330.         } catch (...) {
  331.             delete file;
  332.             throw;
  333.         }
  334.     }
  335. }
  336.  
  337. void ProcessPendingFiles ()
  338. {
  339.     if (gNumPendingFiles == 0)
  340.         return;
  341.     
  342.     try {
  343.         for (short i = 0; i < gNumPendingFiles; ++i) {
  344.             FSSpec                        spec = (*gPendingFiles) [i];
  345.             CClippingFile*                file = new CClippingFile (spec);
  346.             try {
  347.                 CClippingWindow*        window = new CClippingWindow (file);
  348.             } catch (...) {
  349.                 delete file;
  350.                 throw;
  351.             }
  352.         }
  353.     } catch (...) {
  354.         SetHandleSize ((Handle) gPendingFiles, 0);
  355.         gNumPendingFiles = 0;
  356.         throw;
  357.     }
  358.  
  359.     SetHandleSize ((Handle) gPendingFiles, 0);
  360.     gNumPendingFiles = 0;
  361.  
  362. }
  363.  
  364. void QueueUpFileForProcessing (FSSpec* spec)
  365. {
  366.     OSErr        error = PtrAndHand (spec, (Handle) gPendingFiles, sizeof (FSSpec));
  367.     if (error)
  368.         throw error;
  369.  
  370.     WakeUpProcess (&gMyPSN);
  371.     ++gNumPendingFiles;
  372. }
  373.  
  374. void main (void)
  375. {
  376.     short    fRefNum;    
  377.     set_new_handler (NewHandler);    
  378.     
  379.     try {    
  380.         CheckGestalts ();
  381.         Initialize ();
  382.         LoadClippings ();
  383.         CreateMagicWindow ();
  384.         
  385.         while (gRunning)
  386.             EventLoop ();
  387.  
  388.         Finalize ();
  389.     } catch (...) {
  390.         Finalize ();
  391.     }
  392. }
  393.